package com.company.nuwa.mybatis.generator.plugins;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 * <p>批量动态插入</p>
 *
 * @author qww
 * @version 1.0: BatchInsertSelectivePlugin.java
 * @date 2023/4/10  15:32 星期一
 */
public class BatchInsertSelectivePlugin extends PluginAdapter {

    public BatchInsertSelectivePlugin() {
        super();
    }

    @Override
    public boolean validate(List<String> paramList) {
        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
        generateBatchSave(interfaze, introspectedTable);
        return super.clientGenerated(interfaze, introspectedTable);
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {

        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();//数据库表名

        XmlElement parentElement = document.getRootElement();

        List<IntrospectedColumn> columns = introspectedTable.getAllColumns();
        List<IntrospectedColumn> columns1 = introspectedTable.getAllColumns();
        XmlElement batchSaveElement = new XmlElement("insert");
        batchSaveElement.addAttribute(new Attribute("id", "batchInsertSelective"));

        StringBuilder sql = new StringBuilder();
        sql.append(
                "<foreach collection=\"list\" item=\"item\" index=\"index\" separator=\";\" > \n");
        OutputUtilities.xmlIndent(sql, 3);
        sql.append("insert into ").append(tableName).append(" \n");
        OutputUtilities.xmlIndent(sql, 3);
        sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");

        StringBuilder sets = new StringBuilder();

        for (IntrospectedColumn column : columns) {
            OutputUtilities.xmlIndent(sets, 4);
            sets.append("<if test=\"item.").append(column.getJavaProperty()).append(" != null\"> \n");
            OutputUtilities.xmlIndent(sets, 5);
            sets.append(column.getActualColumnName()).append(", ").append("\n");
            OutputUtilities.xmlIndent(sets, 4);
            sets.append("</if> \n");
        }
        OutputUtilities.xmlIndent(sets, 3);
        sets.append("</trim>" + "\n");
        sql.append(sets);

        OutputUtilities.xmlIndent(sql, 3);
        sql.append("<trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\">\n");
        StringBuilder sets1 = new StringBuilder();
        for (IntrospectedColumn column : columns1) {
            OutputUtilities.xmlIndent(sets1, 4);
            sets1.append("<if test=\"item.").append(column.getJavaProperty()).append(" != null\">\n");
            OutputUtilities.xmlIndent(sets1, 5);
            sets1.append(" #{item.").append(column.getJavaProperty()).append(",").append("jdbcType = ").append(
                    column.getJdbcTypeName()).append("},\n");
            OutputUtilities.xmlIndent(sets1, 4);
            sets1.append("</if>\n");
        }
        OutputUtilities.xmlIndent(sets1, 3);
        sets1.append("</trim>" + "\n");
        sql.append(sets1);
        OutputUtilities.xmlIndent(sql, 2);
        sql.append("</foreach>");

        batchSaveElement.addElement(new TextElement(sql.toString()));

        parentElement.addElement(batchSaveElement);

        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    /**
     * 自定义批量插入方法
     * @param interfaze
     * @param introspectedTable
     */
    private void generateBatchSave(Interface interfaze, IntrospectedTable introspectedTable) {

        Method m = new Method("batchInsertSelective");
        m.setVisibility(JavaVisibility.PUBLIC);
        m.setAbstract(true);
        m.setReturnType(FullyQualifiedJavaType.getIntInstance());
        m.addJavaDocLine("/**");
        m.addJavaDocLine("* 批量插入");
        m.addJavaDocLine("* @param list 记录");
        m.addJavaDocLine("* @return int");
        m.addJavaDocLine(" */");
        m.addAnnotation("@Override");
        String type;
        if (!introspectedTable.getRules().generatePrimaryKeyClass()) {
            type = introspectedTable.getBaseRecordType();
        } else {
            type = introspectedTable.getPrimaryKeyType();
        }

        m.addParameter(new Parameter(new FullyQualifiedJavaType("List<" + type + ">"), "list"));

        context.getCommentGenerator().addGeneralMethodComment(m, introspectedTable);

        interfaze.addImportedType(FullyQualifiedJavaType.getNewListInstance());
        interfaze.addImportedType(new FullyQualifiedJavaType(type));
        interfaze.addMethod(m);
    }

}
